package com.yanqu.road.server.gameplayer.module.activity.twins;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.twins.*;
import com.yanqu.road.entity.activity.twins.config.*;
import com.yanqu.road.entity.activity.twins.log.*;
import com.yanqu.road.entity.enums.activity.twins.eTwinsKungFuCombType;
import com.yanqu.road.entity.enums.activity.twins.eTwinsKungFuType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.ePlayerAttrType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.player.UserPatrons;
import com.yanqu.road.logic.bussiness.activity.TwinsBusiness;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.ShareProto;
import com.yanqu.road.pb.activity.TwinsProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.AttributeModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.twins.TwinsDebugMgr;
import com.yanqu.road.server.manger.activity.twins.TwinsMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.commons.beanutils.PropertyUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;


public class TwinsModule extends GeneralModule {

    private AtomicInteger selfIndex = new AtomicInteger(1);
    private AtomicInteger enemyIndex = new AtomicInteger(1);


    private TwinsUserData userData;

    public TwinsModule(GamePlayer player) {
        super(player);
    }

    public TwinsUserData getUserData(){
        return userData;
    }

    public int checkGroup(){
        ActivityInfo activity = TwinsMgr.getActivity();
        if (activity == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        int groupId = GameUnionActivityGroupMgr.getGroupId(activity.getActivityId(), getUserId());
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID) {
            return GameErrorCode.E_TWINS_NO_GROUP;
        }
        return 0;
    }

    public void sendSelf(String content){
        long startTime = System.currentTimeMillis();
        if(ServerListMgr.getChannelId(GameServer.getInstance().getServerId()) != 666){
            return;
        }
        if(content.equals("21860")){
            ShareProto.SaveDeskRewardReqMsg.Builder respMsg = ShareProto.SaveDeskRewardReqMsg.newBuilder();
            player.sendPacket(Protocol.S_DY_BACK_REWARD, respMsg);
        }
        /*TwinsProto.TwinsUserDataReqMsg.Builder respMsg = TwinsProto.TwinsUserDataReqMsg.newBuilder();
        respMsg.setActivityId(9016038);
        player.sendChannelPacket(Protocol.S_TWINS_DATA_SYNC, respMsg);*/
        /*TwinsProto.TwinsIntoPveGameReqMsg.Builder respMsg = TwinsProto.TwinsIntoPveGameReqMsg.newBuilder();
        respMsg.setActivityId(9016038);
        player.sendChannelPacket(Protocol.S_TWINS_INTO_PVE_GAME, respMsg);*/
        /*TwinsProto.TwinsPveGameGetRewardReqMsg.Builder respMsg = TwinsProto.TwinsPveGameGetRewardReqMsg.newBuilder();
        respMsg.setActivityId(9016038);
        respMsg.setType(2);
        player.sendChannelPacket(Protocol.S_TWINS_PVE_GAME_GET_REWARD, respMsg);*/
        /*TwinsProto.TwinsPveGameBattleReqMsg.Builder reqMsg = TwinsProto.TwinsPveGameBattleReqMsg.newBuilder();
        reqMsg.setActivityId(9016038);
        player.sendChannelPacket(Protocol.S_TWINS_INTO_PVE_BATTLE, reqMsg);
        TwinsProto.TwinsPveGameBattleKungFuRefreshReqMsg.Builder respMsg = TwinsProto.TwinsPveGameBattleKungFuRefreshReqMsg.newBuilder();
        respMsg.setActivityId(9016038);
        player.sendChannelPacket(Protocol.S_TWINS_PVE_BATTLE_REFRESH, respMsg);*/
        /*TwinsProto.TwinsPveGameBattleReqMsg.Builder reqMsg = TwinsProto.TwinsPveGameBattleReqMsg.newBuilder();
        reqMsg.setActivityId(9016038);
        player.sendChannelPacket(Protocol.S_TWINS_INTO_PVE_BATTLE, reqMsg);*/
        /*if(content.equals("25557")){
            List<Integer> idList = new ArrayList<>();
            for(TwinsKungFuData kungFuData : userData.getMyKungFuList()){
                idList.add(kungFuData.getId());
            }
            TwinsProto.TwinsPveGameBattleChoiceReqMsg.Builder respMsg = TwinsProto.TwinsPveGameBattleChoiceReqMsg.newBuilder();
            respMsg.setActivityId(TwinsMgr.getActivityId());
            respMsg.setChoiceId(idList.get(0));
            player.sendChannelPacket(Protocol.S_TWINS_PVE_BATTLE_CHOICE, respMsg);
            TwinsProto.TwinsPveGameBattleChoiceReqMsg.Builder reqqMsg = TwinsProto.TwinsPveGameBattleChoiceReqMsg.newBuilder();
        }
        if(content.equals("10086")){
            TwinsDebugMgr.clearEnterRoom();
        }
        if(content.equals("25571")){
            TwinsProto.TwinsPvpEnterMainReqMsg.Builder reqMsg = TwinsProto.TwinsPvpEnterMainReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            player.sendChannelPacket(Protocol.S_TWINS_PVP_ENTER_MAIN, reqMsg);
        }
        if(content.equals("25572")){
            TwinsProto.TwinsPvpEnterBossReqMsg.Builder reqMsg = TwinsProto.TwinsPvpEnterBossReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            reqMsg.setBossId(10001);
            player.sendChannelPacket(Protocol.S_TWINS_PVP_ENTER_BOSS, reqMsg);
        }
        if(content.equals("25573")){
            TwinsProto.TwinsPvpLeaveBossReqMsg.Builder reqMsg = TwinsProto.TwinsPvpLeaveBossReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            reqMsg.setBossId(10001);
            player.sendChannelPacket(Protocol.S_TWINS_PVP_LEAVE_BOSS, reqMsg);
        }
        if(content.equals("25574")){
            TwinsProto.TwinsPvpBeatReqMsg.Builder reqMsg = TwinsProto.TwinsPvpBeatReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            reqMsg.setBossId(10001);
            reqMsg.setUserId(0);
            player.sendChannelPacket(Protocol.S_TWINS_PVP_BEAT, reqMsg);
        }
        if(content.equals("25575")){
            TwinsProto.TwinsPvpGetUserReqMsg.Builder reqMsg = TwinsProto.TwinsPvpGetUserReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            reqMsg.setBossId(10001);
            player.sendChannelPacket(Protocol.S_TWINS_PVP_GET_USER, reqMsg);
        }
        if(content.equals("25579")){
            TwinsProto.TwinsPvpGetUserInfoReqMsg.Builder reqMsg = TwinsProto.TwinsPvpGetUserInfoReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            reqMsg.setAliUserId(280007174L);
            player.sendChannelPacket(Protocol.S_TWINS_PVP_GET_USER_BOOL, reqMsg);
        }
        if(content.equals("25583")){
            TwinsProto.TwinsPvpAttackReqMsg.Builder reqMsg = TwinsProto.TwinsPvpAttackReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            player.sendChannelPacket(Protocol.S_TWINS_PVP_ATTACK, reqMsg);
        }
        if(content.equals("25562")){
            TwinsProto.TwinsLuckDrawReqMsg.Builder reqMsg = TwinsProto.TwinsLuckDrawReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            reqMsg.setTimes(1);
            player.sendChannelPacket(CrossProtocol.C2_CROSS_TWINS_LUCK_DRAW, reqMsg);
        }
        if(content.equals("25563")){
            TwinsProto.TwinsLuckDrawRecordReqMsg.Builder reqMsg = TwinsProto.TwinsLuckDrawRecordReqMsg.newBuilder();
            reqMsg.setActivityId(TwinsMgr.getActivityId());
            player.sendChannelPacket(CrossProtocol.C2_CROSS_TWINS_LUCK_DRAW_RECORD, reqMsg);
        }
        if(content.contains("twinsPvp")){
            List<String> paramList = StringUtils.stringToStringList(content,",");
            if(paramList.size() == 7
                    && StringUtils.isNumber(paramList.get(1))
                    && StringUtils.isNumber(paramList.get(2))
                    && StringUtils.isNumber(paramList.get(3))
                    && StringUtils.isNumber(paramList.get(4))
                    && StringUtils.isNumber(paramList.get(5))
                    && StringUtils.isNumber(paramList.get(6))
            ){
                TwinsDebugMgr.pvpDebug(paramList.get(1),paramList.get(2),paramList.get(3),paramList.get(4),paramList.get(5),paramList.get(6));
            }else{
                TwinsDebugMgr.pvpDebug("1000","100","10","10","0","10");
            }
        }
        if(content.contains("ck")){
            List<Integer> paramList = StringUtils.stringToIntegerList(content,",");
            if(paramList.size() != 2){
                return;
            }
            for(int i = 0;i < paramList.get(1);i++){
                pveDrawKungFu(10);
            }
        }

        if(content.contains("chyaode")){
            List<Integer> paramList = StringUtils.stringToIntegerList(content,",");
            if(paramList.size() != 2){
                return;
            }
            Map<Integer,List<Integer>> drawMap = new ConcurrentHashMap<>();
            for(int num = 5 ; num <= 260 ;num ++ ){
                drawMap.put(num,new ArrayList<>());
            }
            for(int i = 0; i < paramList.get(1);i++){
                int drawTime = 0;
                List<Integer> levelRecordList = new ArrayList<>();
                new ConcurrentHashMap<>();
                Map<Integer, Integer> initKungFuMap = TwinsMgr.getConfig().getOwnKungFuMap();
                Map<Integer, TwinsUserKungFuData> ownKungFuMap = new ConcurrentHashMap<>();
                for(Integer kungFuId : initKungFuMap.keySet()){
                    TwinsKungFuConfig kungFuConfig = TwinsMgr.getConfig().getKungFuConfig(kungFuId,1);
                    TwinsUserKungFuData userKungFuData = new TwinsUserKungFuData();
                    userKungFuData.setKungFuId(kungFuId);
                    userKungFuData.setLevel(initKungFuMap.get(kungFuId));
                    userKungFuData.setExp(0);
                    ownKungFuMap.put(userKungFuData.getKungFuId(),userKungFuData);
                }
                userData.setOwnKungFuMap(ownKungFuMap);
                int allLevel = 0;
                while (drawTime < 100000 && allLevel < 250){
                    drawTime++;
                    pveDrawKungFu(1);
                    allLevel = 0;
                    for(TwinsUserKungFuData userKungFuData : userData.getOwnKungFuMap().values()){
                        TwinsConfig twinsConfig = TwinsMgr.getConfig();
                        TwinsKungFuConfig nextKungFuConfig = twinsConfig.getKungFuConfig(userKungFuData.getKungFuId(),userKungFuData.getLevel() + 1);
                        while (nextKungFuConfig != null && nextKungFuConfig.getCost() <= userKungFuData.getExp()){
                            pveUpgradeKungFu(userKungFuData.getKungFuId());
                            nextKungFuConfig = twinsConfig.getKungFuConfig(userKungFuData.getKungFuId(),userKungFuData.getLevel() + 1);
                        }
                        allLevel = allLevel + userKungFuData.getLevel();
                    }
                    if(!levelRecordList.contains(allLevel)){
                        levelRecordList.add(allLevel);
                        if(!drawMap.containsKey(allLevel)){
                            break;
                        }
                        drawMap.get(allLevel).add(drawTime);
                    }
                }
            }
            for(int level : drawMap.keySet()){
                int maxTimes = 0;
                int minTimes = Integer.MAX_VALUE;
                int allTimes = 0;
                for(int drawTimes : drawMap.get(level)){
                    allTimes = allTimes + drawTimes;
                    if(drawTimes > maxTimes){
                        maxTimes = drawTimes;
                    }
                    if(drawTimes < minTimes){
                        minTimes = drawTimes;
                    }
                }
                int avgTimes = 0;
                if(drawMap.get(level).size() != 0){
                    avgTimes = allTimes/drawMap.get(level).size();
                }
                log.error("抽卡到等级{},{}次模拟平局值{}，最大值{}，最小值{}",level,drawMap.get(level).size(),avgTimes,maxTimes,minTimes);
            }
        }
        long endTime = System.currentTimeMillis();
        log.error("停{}",endTime - startTime);*/
/*
        if(content.contains("tg")){
            List<Integer> paramList = StringUtils.stringToIntegerList(content,",");
            if(paramList.size() != 2){
                return;
            }
            TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(paramList.get(1));
            if(missionConfig != null){
                gameOver();
                userData.setMissionId(missionConfig.getId());
            }
        }*/
        if(content.contains("selfUnion")){
            List<Integer> paramList = StringUtils.stringToIntegerList(content,",");
            if(paramList.size() != 2){
                return;
            }
            TwinsDebugMgr.sendUnionMember(userData.getUserId(),paramList.get(1));
        }
    }


    public void initUserData(int activityId){
        synchronized (this){
            if(userData == null || userData.getActivityId() != activityId){
                TwinsConfig twinsConfig = TwinsMgr.getConfig();
                if(twinsConfig != null){
                    TwinsUserData tempUserData = new TwinsUserData();
                    tempUserData.setActivityId(activityId);
                    tempUserData.setUserId(getUserId());
                    Map<Integer, TwinsUserKungFuData> ownKungFuMap = new ConcurrentHashMap<>();
                    Map<Integer, Integer> initKungFuMap = twinsConfig.getOwnKungFuMap();
                    for(Integer kungFuId : initKungFuMap.keySet()){
                        TwinsKungFuConfig kungFuConfig = twinsConfig.getKungFuConfig(kungFuId,1);
                        if(kungFuConfig == null){
                            log.error("活动{},没有对应的初始化技能等级",twinsConfig.getActivityInfo().getActivityId());
                            return;
                        }
                        TwinsUserKungFuData userKungFuData = new TwinsUserKungFuData();
                        userKungFuData.setKungFuId(kungFuId);
                        userKungFuData.setLevel(initKungFuMap.get(kungFuId));
                        userKungFuData.setExp(0);
                        ownKungFuMap.put(userKungFuData.getKungFuId(),userKungFuData);
                    }
                    tempUserData.setOwnKungFuMap(ownKungFuMap);
                    int beginMissionId;
                    beginMissionId = twinsConfig.getBeginMissionId();
                /*if(StringUtils.isNumber(player.getUserInfo().getOpenId())){
                    if(new BigInteger(player.getUserInfo().getOpenId()).compareTo(BigInteger.valueOf(900)) > 0){
                        beginMissionId = twinsConfig.getLastMissionId();
                    }
                }*/
                    TwinsMissionConfig twinsMissionConfig = twinsConfig.getMissionConfig(beginMissionId);
                    if(twinsMissionConfig == null){
                        log.error("活动{},没有对应的初始化章节",twinsConfig.getActivityInfo().getActivityId());
                        return;
                    }
                    tempUserData.setMissionId(beginMissionId);
                    tempUserData.setHp(twinsConfig.getPveMaxHp());
                    tempUserData.setHpTime(System.currentTimeMillis());
                    tempUserData.setInsertOption();
                    userData = tempUserData;
                }
            }
        }

    }

    //生成进入章节的战斗数据
    private void makeBattleKungFu(TwinsUserData tempUserData){
        TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(tempUserData.getMissionId());
        if(missionConfig != null){
            int bossId = missionConfig.getBossId(0);
            List<Integer> bossInfoList = missionConfig.getBossInfo(bossId);
            userData.setBossId(bossId);
            userData.setBossBool(String.valueOf(bossInfoList.get(0)));
        }
        if(tempUserData.getEmKungFuList().size() == 0){
            List<TwinsKungFuData> emKungFuList = new ArrayList<>();
            emKungFuList.add(TwinsMgr.getBossKungFu(tempUserData.getBossId(),enemyIndex.getAndIncrement(),userData.getMissionId()));
            emKungFuList.add(TwinsMgr.getBossKungFu(tempUserData.getBossId(),enemyIndex.getAndIncrement(),userData.getMissionId()));
            tempUserData.setEmKungFuList(emKungFuList);
        }

        Map<Integer,TwinsUserKungFuData> missUserKuangFuMap = new ConcurrentHashMap<>();
        Map<Integer,TwinsUserKungFuData> bagUserKuangFuMap = new ConcurrentHashMap<>();
        for(TwinsUserKungFuData userKungFuData : tempUserData.getOwnKungFuMap().values()){
            if(userKungFuData.getLevel() == 0)continue;
            TwinsUserKungFuData missData = new TwinsUserKungFuData();
            missData.setKungFuId(userKungFuData.getKungFuId());
            missData.setLevel(userKungFuData.getLevel());
            missUserKuangFuMap.put(missData.getKungFuId(),missData);
            bagUserKuangFuMap.put(missData.getKungFuId(),missData);
        }
        tempUserData.setMissionKungFuMap(missUserKuangFuMap);
        tempUserData.setGameBagKungFuMap(bagUserKuangFuMap);
        //从新开始章节或者初始化的时候没有基础的五张卡的时候开始初始化
        if(tempUserData.getMyKungFuList().size() == 0){
            List<TwinsKungFuData> myKungFuList = new ArrayList<>();
            myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
            myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
            myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
            myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
            myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
            tempUserData.setMyKungFuList(myKungFuList);
        }

        List<Integer> missCombList = new ArrayList<>();
        missCombList.addAll(tempUserData.getUnlockCombList());
        tempUserData.setMissionKungFuCombList(missCombList);


        BigInteger maxBool = new BigInteger(tempUserData.getMaxBool());
        BigInteger maxAttack = new BigInteger(tempUserData.getMaxAttack());
        //是战斗开始菜生效还是战斗没开始就生效
        /*int attackValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.DiyishenjianComb.getValue());
        int boolValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.YihuajuexueComb.getValue());
        maxAttack = maxAttack.multiply(BigInteger.valueOf(attackValue + 1000)).divide(BigInteger.valueOf(1000));
        maxBool = maxBool.multiply(BigInteger.valueOf(boolValue + 1000)).divide(BigInteger.valueOf(1000));*/
        tempUserData.setMissionMaxBool(maxBool.toString());
        tempUserData.setMissionBool(tempUserData.getMissionMaxBool());
        tempUserData.setMissionAttack(maxAttack.toString());
        int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.JiangnanqunxiaComb.getValue());
        int freeTimes = TwinsMgr.getConfig().getResetFreeNum() + combValue;
        tempUserData.setMissionRefeshTimes(freeTimes);
        tempUserData.setRefreshTimes(0);
        tempUserData.setBossRage(0);
    }

    public void syncConfigData(){
        String language = player.getLanguage();
        TwinsConfig config = TwinsMgr.getConfig();
        Map<Integer, Map<Integer, TwinsKungFuConfig>> kungFuConfigMap = config.getKungFuConfigMap();
        Map<Integer, TwinsKungFuCombConfig> kungFuCombConfigMap = config.getKungFuCombConfigMap();
        Map<Integer, TwinsMissionConfig> missionConfigMap = config.getMissionConfigMap();
        Map<Integer, TwinsNpcConfig> npcConfigMap = config.getNpcConfigMap();
        Map<Integer, TwinsLotteryConfig> lotteryConfigMap = config.getLotteryConfigMap();
        Map<Integer, TwinsPvpConfig> pvpConfigMap = config.getPvpConfigMap();
        Map<Integer, TwinsMapConfig> mapConfigMap = config.getMapConfigMap();

        TwinsProto.TwinsConfigDataSyncMsg.Builder configMsg = TwinsProto.TwinsConfigDataSyncMsg.newBuilder();
        configMsg.setActivityId(config.getActivityInfo().getActivityId());
        TwinsProto.TwinsConfigDataTemp.Builder configDataMsg = TwinsProto.TwinsConfigDataTemp.newBuilder();
        for(Map<Integer, TwinsKungFuConfig> kungFuLevelConfigMap : kungFuConfigMap.values()){
            for(TwinsKungFuConfig kungFuConfig : kungFuLevelConfigMap.values()){
                TwinsProto.KungFuConfigTemp.Builder kungfuMsg = TwinsProto.KungFuConfigTemp.newBuilder();
                kungfuMsg.setId(kungFuConfig.getId());
                kungfuMsg.setOriginType(kungFuConfig.getOriginType());
                kungfuMsg.setKungfuType(kungFuConfig.getKungfuType());
                kungfuMsg.setQuality(kungFuConfig.getQuality());
                kungfuMsg.setLevel(kungFuConfig.getLevel());
                kungfuMsg.setIcon(kungFuConfig.getIcon());
                kungfuMsg.setName(ServerLanguageMgr.getContent(kungFuConfig.getName(), language));
                kungfuMsg.setDesc(ServerLanguageMgr.getContent(kungFuConfig.getDesc(), language));
                kungfuMsg.setCost(kungFuConfig.getCost());
                kungfuMsg.setAnger(kungFuConfig.getAnger());
                kungfuMsg.setSkillEffect(kungFuConfig.getSkillEffect());
                kungfuMsg.setHaloType(kungFuConfig.getHaloType());
                kungfuMsg.setRange(kungFuConfig.getRange());
                kungfuMsg.setBlowHarmWeights(kungFuConfig.getBlowHarmWeights());
                kungfuMsg.setRepelRange(kungFuConfig.getRepelRange());
                kungfuMsg.setKungfuDesc(ServerLanguageMgr.getContent(kungFuConfig.getKungfuDesc(), language));
                kungfuMsg.setVibrationAmplitude(kungFuConfig.getVibrationAmplitude());
                kungfuMsg.setFightDesc(ServerLanguageMgr.getContent(kungFuConfig.getFightDesc(), language));
                configDataMsg.addKungfu(kungfuMsg);
            }
        }
        for(TwinsKungFuCombConfig combConfig : kungFuCombConfigMap.values()){
            TwinsProto.KungFuCombConfigTemp.Builder combMsg = TwinsProto.KungFuCombConfigTemp.newBuilder();
            combMsg.setId(combConfig.getId());
            combMsg.setName(ServerLanguageMgr.getContent(combConfig.getName(), language));
            combMsg.setDesc(ServerLanguageMgr.getContent(combConfig.getDesc(), language));
            combMsg.setNeedOriginLevel(combConfig.getNeedOriginLevel());
            combMsg.setNeedKungfuLevel(combConfig.getNeedKungfuLevel());
            combMsg.setSkillEffect(combConfig.getSkillEffect());
            combMsg.setRewards(combConfig.getRewards());
            combMsg.setLevel(combConfig.getLevel());
            combMsg.setEffectDesc(ServerLanguageMgr.getContent(combConfig.getEffectDesc(), language));
            combMsg.setType(combConfig.getType());
            configDataMsg.addKungfuComb(combMsg);
        }

        for(TwinsMissionConfig missionConfig : missionConfigMap.values()){
            TwinsProto.MissionConfigTemp.Builder missionMsg = TwinsProto.MissionConfigTemp.newBuilder();
            missionMsg.setId(missionConfig.getId());
            missionMsg.setType(missionConfig.getType());
            missionMsg.setName(ServerLanguageMgr.getContent(missionConfig.getName(), language));
            missionMsg.setRecommendPower(missionConfig.getRecommendPower());
            missionMsg.setMonsterId(missionConfig.getMonsterId());
            missionMsg.setBossId(missionConfig.getBossId());
            missionMsg.setMonsterPower(missionConfig.getMonsterPower());
            missionMsg.setBossPower(missionConfig.getBossPower());
            missionMsg.setRewards(missionConfig.getRewards());
            missionMsg.setSweepRewards(missionConfig.getSweepRewards());
            missionMsg.setSweepRandomRewards(missionConfig.getSweepRandomRewards());
            missionMsg.setFailRewards(missionConfig.getFailRewards());
            missionMsg.setIsBoss(missionConfig.getIsBoss());
            missionMsg.setMap(missionConfig.getMap());
            missionMsg.setEnergyCost(missionConfig.getEnergyCost());
            configDataMsg.addMission(missionMsg);
        }

        for(TwinsNpcConfig npcConfig : npcConfigMap.values()){
            TwinsProto.NpcConfigTemp.Builder npcMsg = TwinsProto.NpcConfigTemp.newBuilder();
            npcMsg.setId(npcConfig.getId());
            npcMsg.setOrdinaryKungfu(npcConfig.getOrdinaryKungfu());
            npcMsg.setCoreKungfu(npcConfig.getCoreKungfu());
            npcMsg.setAnger(npcConfig.getAnger());
            npcMsg.setIcon(npcConfig.getIcon());
            configDataMsg.addNpc(npcMsg);
        }

        for(TwinsLotteryConfig lotteryConfig : lotteryConfigMap.values()){
            TwinsProto.LotteryConfigTemp.Builder lotteryMsg = TwinsProto.LotteryConfigTemp.newBuilder();
            lotteryMsg.setId(lotteryConfig.getId());
            lotteryMsg.setName(ServerLanguageMgr.getContent(lotteryConfig.getName(), language));
            lotteryMsg.setWeights(lotteryConfig.getWeights());
            lotteryMsg.setRewards(lotteryConfig.getRewards());
            lotteryMsg.setIsHide(lotteryConfig.getIsHide());
            lotteryMsg.setSort(lotteryConfig.getSort());
            configDataMsg.addLottery(lotteryMsg);
        }

        for(TwinsPvpConfig pvpConfig : pvpConfigMap.values()){
            TwinsProto.PvpConfigTemp.Builder pvpMsg = TwinsProto.PvpConfigTemp.newBuilder();
            pvpMsg.setId(pvpConfig.getId());
            pvpMsg.setRecommendPower(pvpConfig.getRecommendPower());
            pvpMsg.setIcon(pvpConfig.getIcon());
            pvpMsg.setName(ServerLanguageMgr.getContent(pvpConfig.getName(), language));
            pvpMsg.setBossPower(pvpConfig.getBossPower());
            pvpMsg.setDesc(ServerLanguageMgr.getContent(pvpConfig.getDesc(), language));
            pvpMsg.setRefreshTime(pvpConfig.getRefreshTime());
            pvpMsg.setDarePoint(pvpConfig.getDarePoint());
            pvpMsg.setRewards(pvpConfig.getRewards());
            pvpMsg.setScoreRewards(pvpConfig.getScoreRewards());
            configDataMsg.addPvpConfig(pvpMsg);
        }

        for(TwinsMapConfig mapConfig : mapConfigMap.values()){
            TwinsProto.MapConfigTemp.Builder mapMsg = TwinsProto.MapConfigTemp.newBuilder();
            mapMsg.setId(mapConfig.getId());
            mapMsg.setDesc(ServerLanguageMgr.getContent(mapConfig.getDesc(), language));
            mapMsg.setNpcId(mapConfig.getNpcId());
            mapMsg.setCoreKungfu(mapConfig.getCoreKungfu());
            mapMsg.setName(ServerLanguageMgr.getContent(mapConfig.getName(), language));

            configDataMsg.addMapConfig(mapMsg);
        }
        configMsg.setConfigData(configDataMsg);
        player.sendPacket(Protocol.U_TWINS_CONFIG_SYNC, configMsg);
    }
    public void syncUserData(){
        int activityId = TwinsMgr.getActivityId();
        int groupId = GameUnionActivityGroupMgr.getGroupId(activityId, player.getUserId());
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return;
        }
        updateCrossUserData();
        TwinsProto.CrossTwinsUserDataMsg.Builder syncMsg = TwinsProto.CrossTwinsUserDataMsg.newBuilder();
        syncMsg.setActivityId(activityId);
        player.sendUnionActivityGroupPacket(Protocol.C2_CROSS_TWINS_PVP_SYNC_USER_DATA, syncMsg,activityId,groupId);
    }

    public void syncUserDataFromCross(TwinsProto.CrossTwinsUserDataMsg crossSyncMsg){
        hpRecovery();
        TwinsProto.TwinsUserDataSyncMsg.Builder syncMsg = TwinsProto.TwinsUserDataSyncMsg.newBuilder();
        syncMsg.setActivityId(TwinsMgr.getActivityId());
        syncMsg.setBool(userData.getMaxBool());
        syncMsg.setAttack(userData.getMaxAttack());
        syncMsg.setMissionId(userData.getMissionId());
        syncMsg.setIsBattle(userData.isEnterMission());
        syncMsg.setHp(userData.getHp());
        syncMsg.setHpTime(userData.getHpTime());
        for(TwinsUserKungFuData userKungFuData : userData.getOwnKungFuMap().values()){
            TwinsProto.TwinsUserKungFuTempMsg.Builder kungfuMsg = TwinsProto.TwinsUserKungFuTempMsg.newBuilder();
            kungfuMsg.setKungfuId(userKungFuData.getKungFuId());
            kungfuMsg.setLevel(userKungFuData.getLevel());
            kungfuMsg.setValue(userKungFuData.getExp());
            syncMsg.addKungFu(kungfuMsg);
        }
        syncMsg.setPvpTimes(crossSyncMsg.getPvpTimes());
        syncMsg.setIsPvpReward(crossSyncMsg.getIsPvpReward());
        player.sendPacket(Protocol.U_TWINS_DATA_SYNC, syncMsg);
        if(syncMsg.getIsPvpReward()){
            TwinsDebugMgr.removeRoom(player.getUserId());
        }
    }

    //更新玩家血量等
    public void updateCrossUserData(){
        ActivityInfo activityInfo = TwinsMgr.getActivity();
        if(activityInfo == null){
            return;
        }
        int activityId = activityInfo.getActivityId();
        int groupId = GameUnionActivityGroupMgr.getGroupId(activityId, player.getUserId());
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID){
            return;
        }
        //没初始化的不发
        if (userData == null){
            return;
        }
        TwinsProto.CrossTwinsPvpUpdateUserDataReqMsg.Builder updateMsg = TwinsProto.CrossTwinsPvpUpdateUserDataReqMsg.newBuilder();
        updateMsg.setActivityId(TwinsMgr.getActivityId());
        TwinsProto.CrossTwinsPvpUpdateUserMsg.Builder userMsg = TwinsProto.CrossTwinsPvpUpdateUserMsg.newBuilder();
        userMsg.setUserId(userData.getUserId());
        userMsg.setBool(userData.getMaxBool());
        userMsg.setAttack(userData.getMaxAttack());
        UserBaseInfo userBaseInfo = UserMgr.getUserBaseInfo(getUserId(), GameServer.getInstance().getServerId());
        if(userBaseInfo != null){
            userMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        }
        updateMsg.addUser(userMsg);
        player.sendUnionActivityGroupPacket(CrossProtocol.C2_CROSS_TWINS_PVP_UPDATE_USER,updateMsg,activityId,groupId);
    }

    //检测hp恢复
    private void hpRecovery(){
        long nowTime = System.currentTimeMillis();
        TwinsConfig config = TwinsMgr.getConfig();
        if(config == null || userData.getHp() >= config.getPveMaxHp()){
            return;
        }
        long hpRecoveryTime = config.getPveHpCd() * 1000;
        int hpRecoveryNum = config.getPveHpRecovery();
        long passTime = nowTime - userData.getHpTime();
        if(passTime >= hpRecoveryTime){
            long recTimes = passTime/hpRecoveryTime;
            long recNum = recTimes * hpRecoveryNum;
            if(userData.getHp() + recNum >= config.getPveMaxHp()){
                userData.setHp(config.getPveMaxHp());
                userData.setHpTime(nowTime);
            }else{
                userData.setHp(userData.getHp() + (int)recNum);
                userData.setHpTime(userData.getHpTime() + recTimes * hpRecoveryTime);
            }
        }
    }

    public void hpAdd(long hpNum){
        hpRecovery();
        userData.setHp(userData.getHp() + (int)hpNum);
        syncUserData();
    }

    public void pvpHpAdd(long hpNum){
        TwinsProto.CrossTwinsPvpHpAddReqMsg.Builder reqMsg = TwinsProto.CrossTwinsPvpHpAddReqMsg.newBuilder();
        int activityId = TwinsMgr.getActivityId();
        reqMsg.setActivityId(activityId);
        reqMsg.setAddValue((int)hpNum);
        int groupId = GameUnionActivityGroupMgr.getGroupId(activityId, player.getUserId());

        player.sendUnionActivityGroupPacket(Protocol.C2_CROSS_TWINS_PVP_HP_ADD, reqMsg,activityId,groupId);
    }

    //扣hp
    private void hpReduce(int hp){
        hpRecovery();
        TwinsConfig config = TwinsMgr.getConfig();
        if(config == null){
            log.error("绝代双骄pve的扣除hp找不到配置设置成0了");
            userData.setHp(0);
            userData.setHpTime(System.currentTimeMillis());
            return;
        }
        int oHp = userData.getHp();
        userData.setHp(userData.getHp() - hp);
        if(oHp >= config.getPveMaxHp() && userData.getHp() < config.getPveMaxHp()){
            userData.setHpTime(System.currentTimeMillis());
        }
    }


    /**
     * 系统解锁
     */
    public void initSystem() {
        if (!SystemOpenMgr.systemOpen(player,eSystemId.TwinsActivity.getValue())){
            return;
        }
        if(TwinsMgr.getConfig() != null){
            ActivityInfo activityInfo = TwinsMgr.getConfig().getActivityInfo();
            if(activityInfo != null && checkGroup() == 0){
                initUserData(activityInfo.getActivityId());
                calUserData();
                updateCrossUserData();
                syncConfigData();
                syncUserData();
                player.notifyListener(eGamePlayerEventType.TwinsKangfuComb.getValue(),new ConcurrentHashMap<>(userData.getOwnKungFuMap()));
                player.notifyListener(eGamePlayerEventType.TwinsKangfuAllLevel.getValue(),getAllKangFuLevel());
            }
        }
    }

    private int getAllKangFuLevel(){
        int allLevel = 0;
        for(TwinsUserKungFuData kungFuData : userData.getOwnKungFuMap().values()){
            allLevel = allLevel + kungFuData.getLevel();
        }
        return allLevel;
    }

    @Override
    public boolean loadData() {
        if(SystemOpenMgr.systemOpen(player, eSystemId.TwinsActivity.getValue()) && checkGroup() == 0){
            int maxTwinsMissionId = TwinsBusiness.getUserMaxMissionId(getUserId());
            if(player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.TwinsAutoPassMissionId) < maxTwinsMissionId){
                player.getModule(AttributeModule.class).setAttribute(ePlayerAttrType.TwinsAutoPassMissionId,maxTwinsMissionId);
            }
            TwinsConfig config = TwinsMgr.getConfig();
            if(config != null){
                ActivityInfo activityInfo = config.getActivityInfo();
                if(activityInfo != null){
                    userData = TwinsBusiness.getUserData(getUserId(),activityInfo.getActivityId());
                    if(userData == null){
                        initUserData(activityInfo.getActivityId());
                        calUserData();
                        updateCrossUserData();
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if(userData != null){
            if(userData.isInsertOption()){
                TwinsBusiness.addUserData(userData);
            }else if(userData.isUpdateOption()){
                TwinsBusiness.updateUserData(userData);
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        TwinsDebugMgr.removeDebugUser(getUserId());
        if(SystemOpenMgr.systemOpen(player, eSystemId.TwinsActivity.getValue()) && checkGroup() == 0){
            TwinsConfig config = TwinsMgr.getConfig();
            if(config != null){
                ActivityInfo activityInfo = TwinsMgr.getConfig().getActivityInfo();
                if(activityInfo != null){
                    initUserData(activityInfo.getActivityId());
                    calUserData();
                    updateCrossUserData();
                    syncConfigData();
                    syncUserData();
                    player.notifyListener(eGamePlayerEventType.TwinsKangfuComb.getValue(),new ConcurrentHashMap<>(userData.getOwnKungFuMap()));
                    player.notifyListener(eGamePlayerEventType.TwinsKangfuAllLevel.getValue(),getAllKangFuLevel());
                }
            }
        }
    }


    //进入pve画面
    public void enterPveGame() {
        TwinsProto.TwinsIntoPveGameRespMsg.Builder respMsg = TwinsProto.TwinsIntoPveGameRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setMissionId(userData.getMissionId());
        player.sendPacket(Protocol.U_TWINS_INTO_PVE_GAME, respMsg);
    }

    public void getPveReward(int type ,int missionId) {
        TwinsProto.TwinsPveGameGetRewardRespMsg.Builder respMsg = TwinsProto.TwinsPveGameGetRewardRespMsg.newBuilder();
        respMsg.setRet(0);
        if(type == 1){
            respMsg.setRet(GameErrorCode.E_TWINS_GET_REWARD_PARAMS);
        }else if(type == 2){
            respMsg.setRet(GameErrorCode.E_TWINS_GET_REWARD_CD);
        }else{
            respMsg.setRet(GameErrorCode.E_TWINS_GET_REWARD_PARAMS);
        }
        player.sendPacket(Protocol.U_TWINS_PVE_GAME_GET_REWARD, respMsg);
    }


    public void pveChangeMission(int hangUpMissionId) {
        TwinsProto.TwinsChangeHangUpMissionRespMsg.Builder respMsg = TwinsProto.TwinsChangeHangUpMissionRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setRet(GameErrorCode.E_TWINS_HANG_UP_MISSION);
        player.sendPacket(Protocol.U_TWINS_CHANGE_HANG_UP_MISSION, respMsg);
    }

    //进入战斗，判断下有没有cd，或者是有没有道具可以进去打
    public void enterPveGameBattle() {
        hpRecovery();
        TwinsProto.TwinsPveGameBattleRespMsg.Builder respMsg = TwinsProto.TwinsPveGameBattleRespMsg.newBuilder();
        respMsg.setRet(0);
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        TwinsMissionConfig missionConfig = twinsConfig.getMissionConfig(userData.getMissionId());
        int hpReduce = missionConfig.getEnergyCost();
        //还没用门票进去，看看有时间用时间，没时间用道具
        if(!userData.isEnterMission()){
            if(userData.getHp() >= hpReduce){
                hpReduce(hpReduce);
                makeBattleKungFu(userData);
                userData.setEnterMission(true);
            }else{
                respMsg.setRet(GameErrorCode.E_TWINS_ENTER_MISSION_CD);
                player.sendPacket(Protocol.U_TWINS_INTO_PVE_BATTLE, respMsg);
                return;
            }
        }
        respMsg.setBossId(userData.getBossId());
        respMsg.setMyBool(userData.getMissionBool());
        respMsg.setEnemyBool(userData.getBossBool());
        respMsg.setRefreshTimes(userData.getRefreshTimes());
        for(TwinsKungFuData kungFuData : userData.getUpKungFuList()){
            respMsg.addReadyKungFu(parseKungFuTempMsg(kungFuData));
        }
        for(TwinsKungFuData kungFuData : userData.getMyKungFuList()){
            respMsg.addMyKungFu(parseKungFuTempMsg(kungFuData));
        }
        for(TwinsKungFuData kungFuData : userData.getEmKungFuList()){
            respMsg.addEnemyKungFu(parseKungFuTempMsg(kungFuData));
        }
        respMsg.setMaxBool(userData.getMissionMaxBool());
        respMsg.setAttack(userData.getMissionAttack());
        respMsg.setAnger(userData.getBossRage());
        respMsg.setHp(userData.getHp());
        respMsg.setHpTime(userData.getHpTime());
        for(int combId : userData.getMissionKungFuCombList()){
            TwinsKungFuCombConfig combConfig = twinsConfig.getKungFuCombConfig(combId);
            if(combConfig != null){
                TwinsProto.TwinsKungFuCombMsg.Builder combMsg = TwinsProto.TwinsKungFuCombMsg.newBuilder();
                combMsg.setType(combConfig.getType());
                combMsg.setLevel(combConfig.getLevel());
                respMsg.addComb(combMsg);
            }
        }
        player.sendPacket(Protocol.U_TWINS_INTO_PVE_BATTLE, respMsg);
    }

    private String passMissionReward(){
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        TwinsMissionConfig missionConfig = twinsConfig.getMissionConfig(userData.getMissionId());
        Property passReward = new Property();
        passReward.addProperty(PropertyHelper.parseStringToProperty(missionConfig.getSweepRewards()));
        String randomReward = TwinsMgr.randomMopUpReward(userData.getMissionId());
        passReward.addProperty(PropertyHelper.parseStringToProperty(randomReward));
        player.getModule(CurrencyModule.class).addCurrency(missionConfig.getRewards(),eLogMoneyType.Twins,eLogMoneyType.TwinsPveFirstPassMissionReward);
        player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parsePropertyToString(passReward),eLogMoneyType.Twins,eLogMoneyType.TwinsPvePassMissionReward);

        Property allReward = PropertyHelper.parseStringToProperty(missionConfig.getRewards());
        allReward.addProperty(passReward);

        return PropertyHelper.parsePropertyToString(allReward);
    }

    //自动通关
    public void autoPveGameBattle() {
        hpRecovery();
        TwinsProto.TwinsPveGameAutoBattleRespMsg.Builder respMsg = TwinsProto.TwinsPveGameAutoBattleRespMsg.newBuilder();
        respMsg.setRet(0);
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        TwinsMissionConfig missionConfig = twinsConfig.getMissionConfig(userData.getMissionId());
        int hpReduce = missionConfig.getEnergyCost();
        //还没用门票进去，看看有时间用时间，没时间用道具
        if(!userData.isEnterMission()){
            if(userData.getHp() >= hpReduce){
                List<Long> recommendPowerList = missionConfig.getRecommendPowerList();
                BigInteger bool = new BigInteger(userData.getMaxBool());
                BigInteger attack = new BigInteger(userData.getMaxAttack());
                if(bool.compareTo(BigInteger.valueOf(recommendPowerList.get(0))) < 0 || attack.compareTo(BigInteger.valueOf(recommendPowerList.get(1))) < 0){
                    respMsg.setRet(GameErrorCode.E_TWINS_PVE_AUTO_BATTLE_CANT);
                    player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
                    return;
                }
                int nextMissionId = TwinsMgr.getNextMissionId(userData.getMissionId());
                //最后一关通不了
                if(nextMissionId == 0){
                    respMsg.setRet(GameErrorCode.E_TWINS_PVE_AUTO_BATTLE_LAST_MISSION);
                    player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
                    return;
                }
                //自动通关小于配置的最小关卡，不能自动通关
                if(userData.getMissionId() < twinsConfig.getAutoMinMissionId()){
                    respMsg.setRet(GameErrorCode.E_TWINS_PVE_AUTO_BATTLE_MISSION_CANT);
                    player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
                    return;
                }
                //boss关卡不能自动改通关
                if(missionConfig.getIsBoss() == 1){
                    respMsg.setRet(GameErrorCode.E_TWINS_PVE_AUTO_BATTLE_MISSION_BOSS);
                    player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
                    return;
                }
                //新增必须通关过一次的关卡才能自动
                if(userData.getMissionId() > player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.TwinsAutoPassMissionId)){
                    respMsg.setRet(GameErrorCode.E_TWINS_PVE_AUTO_BATTLE_HISTORY_CANT);
                    player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
                    return;
                }
                hpReduce(hpReduce);
                respMsg.setMissionId(userData.getMissionId());
                respMsg.setReward(passMissionReward());
                userData.setMissionId(nextMissionId);
                TwinsMissionDamageArgs args = new TwinsMissionDamageArgs(BigInteger.valueOf(respMsg.getMissionId()),"0");
                player.notifyListener(eGamePlayerEventType.TwinsPassDamageRank.getValue(),args);
            }else{
                respMsg.setRet(GameErrorCode.E_TWINS_ENTER_MISSION_CD);
                player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
                return;
            }
        }
        player.sendPacket(Protocol.U_TWINS_PVE_AUTO_BATTLE, respMsg);
        syncUserData();
    }

    private TwinsProto.TwinsKungFuTempMsg.Builder parseKungFuTempMsg(TwinsKungFuData kungFuData){
        TwinsProto.TwinsKungFuTempMsg.Builder tempMsg = TwinsProto.TwinsKungFuTempMsg.newBuilder();
        tempMsg.setId(kungFuData.getId());
        tempMsg.setKungFuId(kungFuData.getKungFuId());
        tempMsg.setLevel(kungFuData.getLevel());
        tempMsg.setAnger(kungFuData.getAnger());
        tempMsg.setIsAnger(kungFuData.isNuqi());
        return tempMsg;
    }


    //刷新卡牌
    public void pveGameRefreshKungFu() {
        TwinsProto.TwinsPveGameBattleKungFuRefreshRespMsg.Builder respMsg = TwinsProto.TwinsPveGameBattleKungFuRefreshRespMsg.newBuilder();
        respMsg.setRet(0);
        if(!userData.isEnterMission()){
            respMsg.setRet(GameErrorCode.E_TWINS_MISSION_NOT_START);
            player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_REFRESH, respMsg);
            return;
        }
        int freeTimes = userData.getMissionRefeshTimes();
        if(freeTimes == 0){
            int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.JiangnanqunxiaComb.getValue());
            freeTimes = TwinsMgr.getConfig().getResetFreeNum() + combValue;
        }
        String resetCost = TwinsMgr.getConfig().getResetCost();
        if(userData.getRefreshTimes() >= freeTimes){
            if(!player.getModule(CurrencyModule.class).currencyIsEnough(PropertyHelper.parseStringToProperty(resetCost))){
                respMsg.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
                player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_REFRESH, respMsg);
                return;
            }
            player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(resetCost),eLogMoneyType.Twins,eLogMoneyType.TwinsPveKungFuReset);
        }
        userData.setRefreshTimes(userData.getRefreshTimes() + 1);
        int needCount = userData.getMyKungFuList().size();
        List<TwinsKungFuData> refreshList = new ArrayList<>();
        for(int i = 0; i < needCount; i++){
            refreshList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
        }
        userData.setMyKungFuList(refreshList);
        for(TwinsKungFuData kungFuData : refreshList){
            respMsg.addNewKungFu(parseKungFuTempMsg(kungFuData));
        }
        player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_REFRESH, respMsg);
    }

    private TwinsKungFuData getKungFuCard(int id){
        List<TwinsKungFuData> kungFuDataList = userData.getMyKungFuList();
        for(TwinsKungFuData kungFuData : kungFuDataList){
            if(kungFuData.getId() == id){
                return kungFuData;
            }
        }
        return null;
    }

    //日志格式，武学|等级;武学|等级;
    private String makeLogKungFu(List<TwinsKungFuData> upKungFuDataList){
        String ret = "";
        for(TwinsKungFuData twinsKungFuData : upKungFuDataList){
            ret = ret + twinsKungFuData.getKungFuId() + "|" + twinsKungFuData.getLevel() + ";";
        }
        return ret;
    }

    private void setHistoryMaxAttackValue(TwinsProto.TwinsPveGameBattleChoiceRespMsg.Builder respMsg){
        if(userData.getMissionId() == TwinsMgr.getConfig().getLastMissionId()){
            respMsg.setHistoryAttackValue(userData.getMissionMaxAttackValue());
            BigInteger historyAttackValue = new BigInteger(userData.getMissionMaxAttackValue());
            BigInteger nowAttackValue = new BigInteger(userData.getBossBool());
            nowAttackValue = BigInteger.ZERO.subtract(nowAttackValue);
            if(nowAttackValue.equals(BigInteger.ONE)){
                nowAttackValue = BigInteger.ZERO;
            }
            if(historyAttackValue.compareTo(nowAttackValue) < 0){
                userData.setMissionMaxAttackValue(nowAttackValue.toString());
            }
        }
    }
    //上卡
    public void pveGameKungFuUp(int choiceId) {
        TwinsProto.TwinsPveGameBattleChoiceRespMsg.Builder respMsg = TwinsProto.TwinsPveGameBattleChoiceRespMsg.newBuilder();
        respMsg.setRet(0);
        if(!userData.isEnterMission()){
            respMsg.setRet(GameErrorCode.E_TWINS_MISSION_NOT_START);
            player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_CHOICE, respMsg);
            return;
        }
        LogTwinsPveBattle log = new LogTwinsPveBattle();
        log.setActivityId(userData.getActivityId());
        log.setUserId(userData.getUserId());
        log.setMissionId(userData.getMissionId());
        log.setBossId(userData.getBossId());
        log.setRefreshTimes(userData.getRefreshTimes());
        log.setKungfuValue(makeLogKungFu(userData.getUpKungFuList()));
        log.setBossKungfuValue(makeLogKungFu(userData.getEmKungFuList()));
        BigInteger userOBool = new BigInteger(userData.getMissionBool());
        BigInteger bossOBool = new BigInteger(userData.getBossBool());
        log.setAttackValue("0|" + userOBool.toString());
        log.setBossAttackValue("0|" + bossOBool.toString());
        log.setIsPass(0);
        log.setRandomReward("");
        log.setPassReward("");
        log.setFailReward("");
        log.setTime(System.currentTimeMillis());
        //传0就是投降
        if(choiceId == 0){
            TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(userData.getMissionId());
            player.getModule(CurrencyModule.class).addCurrency(missionConfig.getFailRewards(),eLogMoneyType.Twins,eLogMoneyType.TwinsPveGiveUpMissionReward);
            respMsg.setReward(missionConfig.getFailRewards());
            respMsg.setBossId(userData.getBossId());
            respMsg.setMyBool(userData.getMissionBool());
            respMsg.setEnemyBool(userData.getBossBool());
            respMsg.setRefreshTime(userData.getRefreshTimes());
            respMsg.setAnger(userData.getBossRage());
            setHistoryMaxAttackValue(respMsg);
            gameOver();
            player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_CHOICE, respMsg);
            syncUserData();
            log.setFailReward(missionConfig.getFailRewards());
            return;
        }
        TwinsKungFuData kungFuData = getKungFuCard(choiceId);
        if(kungFuData == null){
            respMsg.setRet(GameErrorCode.E_TWINS_KUNGFU_NOT_EXIT);
            player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_CHOICE, respMsg);
            return;
        }
        List<TwinsKungFuData> kungFuDataList = userData.getMyKungFuList();
        kungFuDataList.remove(kungFuData);
        userData.setMyKungFuList(kungFuDataList);
        List<TwinsKungFuData> upKungFuDataList = userData.getUpKungFuList();
        upKungFuDataList.add(kungFuData);
        userData.setUpKungFuList(upKungFuDataList);
        int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.ShidaerenComb.getValue());
        kungFuData.setAnger(TwinsMgr.randomAnger(kungFuData.getKungFuId(),kungFuData.getLevel(),combValue,userData.getMissionId()));
        kungFuData.setNuqi(false);
        log.setKungfuValue(makeLogKungFu(upKungFuDataList));
        //一张卡没有变化，两张卡进入战斗
        boolean isSyncUserData = false;
        if(upKungFuDataList.size() == 2){
            List<TwinsBattleData> battleList = processBattle();
            for(TwinsBattleData battleData : battleList){
                TwinsProto.TwinsKungFuBattleTempMsg.Builder battleMsg = TwinsProto.TwinsKungFuBattleTempMsg.newBuilder();
                battleMsg.setId(battleData.getKungFuId());
                battleMsg.setValue((int)(new BigInteger(battleData.getValue())).longValue());
                battleMsg.setValue2(battleData.getValue2());
                battleMsg.setFight(battleData.getAnger());
                respMsg.addBattleProcess(battleMsg);
            }
            //我死了，比赛结束重新开始，我赢了(赢了boss还有下一个boss，后面没有boss了直接要下一章了)
            if(userData.getMissionBool().equals("0") || userData.getBossBool().equals("0")){
                if(userData.getBossBool().equals("0")){
                    int nextBossId = TwinsMgr.getNextBossId(userData.getMissionId(),userData.getBossId());
                    if(nextBossId != 0){
                        nextBoss();
                    }else {
                        TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(userData.getMissionId());
                        Property passReward = new Property();
                        passReward.addProperty(PropertyHelper.parseStringToProperty(missionConfig.getSweepRewards()));
                        String randomReward = TwinsMgr.randomMopUpReward(userData.getMissionId());
                        passReward.addProperty(PropertyHelper.parseStringToProperty(randomReward));

                        player.getModule(CurrencyModule.class).addCurrency(missionConfig.getRewards(),eLogMoneyType.Twins,eLogMoneyType.TwinsPveFirstPassMissionReward);
                        player.getModule(CurrencyModule.class).addCurrency(PropertyHelper.parsePropertyToString(passReward),eLogMoneyType.Twins,eLogMoneyType.TwinsPvePassMissionReward);
                        nextMission();
                        Property clientReward = PropertyHelper.parseStringToProperty(missionConfig.getRewards());
                        clientReward.addProperty(passReward);
                        respMsg.setReward(PropertyHelper.parsePropertyToString(clientReward));
                        setHistoryMaxAttackValue(respMsg);
                        isSyncUserData = true;
                        log.setIsPass(1);
                        log.setRandomReward(randomReward);
                        log.setPassReward(missionConfig.getSweepRewards());
                    }
                }else{
                    TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(userData.getMissionId());
                    player.getModule(CurrencyModule.class).addCurrency(missionConfig.getFailRewards(),eLogMoneyType.Twins,eLogMoneyType.TwinsPveFailMissionReward);
                    respMsg.setReward(missionConfig.getFailRewards());
                    setHistoryMaxAttackValue(respMsg);
                    gameOver();
                    isSyncUserData = true;
                    log.setFailReward(missionConfig.getFailRewards());
                }
            }else{
                nextProcess();
            }
        }
        BigInteger userNBool = new BigInteger(userData.getMissionBool());
        BigInteger bossNBool = new BigInteger(userData.getBossBool());
        log.setAttackValue(userOBool.subtract(userNBool).toString() + "|" + userNBool.toString());
        log.setBossAttackValue( bossOBool.subtract(bossNBool).toString()+ "|" + bossNBool.toString());

        respMsg.setBossId(userData.getBossId());
        respMsg.setMyBool(userData.getMissionBool());
        respMsg.setEnemyBool(userData.getBossBool());
        respMsg.setRefreshTime(userData.getRefreshTimes());
        respMsg.setAnger(userData.getBossRage());

        //上的卡只能一张或者两张
        for(TwinsKungFuData tempKungFuData : userData.getUpKungFuList()){
            respMsg.addReadyKungFu(parseKungFuTempMsg(tempKungFuData));
        }
        //我下面的卡只能三张四张五张
        for(TwinsKungFuData tempKungFuData : userData.getMyKungFuList()){
            respMsg.addMyKungFu(parseKungFuTempMsg(tempKungFuData));
        }
        //怪物的卡一直都是两张
        for(TwinsKungFuData tempKungFuData : userData.getEmKungFuList()){
            respMsg.addEnemyKungFu(parseKungFuTempMsg(tempKungFuData));
        }
        player.sendPacket(Protocol.U_TWINS_PVE_BATTLE_CHOICE, respMsg);
        if(isSyncUserData){
            syncUserData();
        }

        LogMgr.addLogTwinsPveBattle(log);
    }

    //生成一张卡的战斗
    private TwinsBattleData makeBattleData(TwinsBattleResultData battleResultData,boolean myCard,TwinsKungFuData battleKungFu){
        TwinsBattleData battleData = new TwinsBattleData();
        battleData.setMyCard(myCard);
        battleData.setValue("0");
        battleData.setValue2("0");
        TwinsMissionConfig twinsMissionConfig = TwinsMgr.getConfig().getMissionConfig(userData.getMissionId());
        List<Integer> bossInfoList = twinsMissionConfig.getBossInfo(userData.getBossId());
        int bossAttack = bossInfoList.get(1);
        int myAttack = Integer.valueOf(userData.getMissionAttack());

        //最后一下普工为0
        if(battleKungFu == null){
            battleData.setKfId(0);
            battleData.setKungFuId(0);
            battleData.setLevel(0);
            battleData.setValue2("0");
            if(myCard){
                int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.JuedaishuangjiaoComb.getValue());
                BigDecimal nowAttack = getBuffAndReduceAttackVersion2(battleResultData,BigDecimal.valueOf(myAttack),false);
                nowAttack = nowAttack.multiply(BigDecimal.valueOf(combValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
                battleData.setMyCard(true);
                battleData.setAnger(0);
                battleData.setValue(nowAttack.toBigInteger().toString());
                battleData.setAttackValue(nowAttack.toBigInteger().toString());
                //加怒气
                userData.setBossRage(userData.getBossRage() + TwinsMgr.getConfig().getBossAngerAdd());
            }else if(!myCard){
                BigDecimal nowAttack = getBuffAndReduceAttackVersion2(battleResultData,BigDecimal.valueOf(bossAttack),true);
                battleData.setMyCard(false);
                battleData.setAnger(1);
                battleData.setValue(nowAttack.toBigInteger().toString());
                battleData.setAttackValue(nowAttack.toBigInteger().toString());
            }
            return battleData;
        }

        TwinsKungFuConfig kungFuConfig = TwinsMgr.getConfig().getKungFuConfig(battleKungFu.getKungFuId(),battleKungFu.getLevel());
        int param1 = kungFuConfig.getSkillEffectList().get(2);
        if(kungFuConfig.getKungfuType() == eTwinsKungFuType.Sword.getValue()){
            //加上百分比
            int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.SwordComb.getValue());
            //李俊伟 9-5 16:09:12
            //我举个例子吧
            //李俊伟 9-5 16:09:56
            //比如我的基础攻击力是100，剑法1是10%的加成，剑法2是20%的加成
            //李俊伟 9-5 16:10:24
            //那么你给我的第一个是value1：10，value2：110
            //李俊伟 9-5 16:10:36
            //第二个是value1：20，value2：130

            //敌人受到攻击伤害提升{0}
            BigDecimal value1 = BigDecimal.valueOf(param1);
            if(myCard){
                value1 = value1.add(BigDecimal.valueOf(combValue));
                BigDecimal addAttackValue = BigDecimal.valueOf(myAttack);
                addAttackValue = addAttackValue.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
                //草，改来改去的，先留着明天又要改回来了
//                addAttackValue = addAttackValue.multiply(BigDecimal.valueOf(combValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
                //设置提升了多少值
                battleData.setValue(addAttackValue.toBigInteger().toString());
                battleResultData.setAddAttackValue(battleResultData.getAddAttackValue() + addAttackValue.intValue());
                battleData.setValue2(getBuffAndReduceAttackVersion2(battleResultData,BigDecimal.valueOf(myAttack),false).toBigInteger().toString());
            }else{
                BigDecimal addAttackValue = BigDecimal.valueOf(bossAttack);
                addAttackValue = addAttackValue.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
                //设置提升了多少值
                battleData.setValue(addAttackValue.toBigInteger().toString());
                battleResultData.setBossAddAttackValue(battleResultData.getBossAddAttackValue() + addAttackValue.intValue());
                battleData.setValue2(getBuffAndReduceAttackVersion2(battleResultData,BigDecimal.valueOf(bossAttack),true).toBigInteger().toString());
            }
        }else if(kungFuConfig.getKungfuType() == eTwinsKungFuType.Palm.getValue()){
            //加上百分比
            int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.PalmComb.getValue());
            //降低对方攻击力X%
            BigDecimal value1 = BigDecimal.valueOf(param1);
            if(myCard){
                value1 = value1.add(BigDecimal.valueOf(combValue));
                BigDecimal reduceAttackValue = BigDecimal.valueOf(bossAttack);
                reduceAttackValue = reduceAttackValue.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
//                reduceAttackValue = reduceAttackValue.multiply(BigDecimal.valueOf(combValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);

                //设置降低了boss多少值
                battleData.setValue(reduceAttackValue.toBigInteger().toString());
                battleResultData.setBossReduceAttackValue(battleResultData.getBossReduceAttackValue() + reduceAttackValue.intValue());
                battleData.setValue2(getBuffAndReduceAttackVersion2(battleResultData,BigDecimal.valueOf(bossAttack),true).toBigInteger().toString());
            }else{
                BigDecimal reduceAttackValue = BigDecimal.valueOf(myAttack);
                reduceAttackValue = reduceAttackValue.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
                //设置降低了boss多少值
                battleData.setValue(reduceAttackValue.toBigInteger().toString());
                battleResultData.setReduceAttackValue(battleResultData.getReduceAttackValue() + reduceAttackValue.intValue());
                battleData.setValue2(getBuffAndReduceAttackVersion2(battleResultData,BigDecimal.valueOf(myAttack),false).toBigInteger().toString());
            }
        }else if(kungFuConfig.getKungfuType() == eTwinsKungFuType.Fist.getValue()){
            //拳法组合效果直接加上去
            int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.FistComb.getValue());

            if(myCard){
                //减少对面投点*点
                BigDecimal value1 = BigDecimal.valueOf(param1 + combValue);
                battleData.setValue(value1.toString());
                //value2要扣掉多少后还剩多少，外面扣
                battleData.setReduceFaceAnger(value1.intValue());
            }else{
                BigDecimal value1 = BigDecimal.valueOf(param1);
                battleData.setValue(value1.toString());
                //value2要扣掉多少后还剩多少，外面扣
                battleData.setReduceFaceAnger(value1.intValue());
            }
        }else if(kungFuConfig.getKungfuType() == eTwinsKungFuType.Sabre.getValue()){
            //加上百分比
            int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.SabreComb.getValue());
            BigDecimal value1 = BigDecimal.valueOf(param1);
            //直接造成X%*攻击力伤害
            BigDecimal nowAttack = BigDecimal.ZERO;
            if(myCard){
                value1 = value1.add(BigDecimal.valueOf(combValue));
                nowAttack = BigDecimal.valueOf(myAttack);
                nowAttack = nowAttack.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
//                nowAttack = nowAttack.multiply(BigDecimal.valueOf(combValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
            }else{
                nowAttack = BigDecimal.valueOf(bossAttack);
                nowAttack = nowAttack.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
            }
            battleData.setValue(nowAttack.toBigInteger().toString());
            battleData.setValue2(nowAttack.toBigInteger().toString());
            battleData.setAttackValue(nowAttack.toBigInteger().toString());
        }else if(kungFuConfig.getKungfuType() == eTwinsKungFuType.IntSkill.getValue()){
            //回血百分比
            int combValue = TwinsMgr.getCombAdd(userData.getMissionKungFuCombList(), eTwinsKungFuCombType.IntSkillComb.getValue());
            BigDecimal value1 = BigDecimal.valueOf(param1);

            //回复血量X%*攻击力
            BigDecimal nowAttack = BigDecimal.ZERO;
            if(myCard){
                nowAttack = BigDecimal.valueOf(myAttack);
                value1 = value1.add(BigDecimal.valueOf(combValue));
                nowAttack = nowAttack.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
//                nowAttack = nowAttack.multiply(BigDecimal.valueOf(combValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
            }else{
                nowAttack = BigDecimal.valueOf(bossAttack);
                nowAttack = nowAttack.multiply(value1).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
            }
            battleData.setValue(nowAttack.toBigInteger().toString());
            battleData.setValue2(nowAttack.toBigInteger().toString());
            battleData.setRecoveryValue(nowAttack.toBigInteger().toString());
        }

        return battleData;
    }

    //算出这一张卡打出来后攻击力变成多少了，谁打的卡就算谁的
    private BigDecimal getBuffAndReduceAttack(TwinsBattleResultData battleResultData, BigDecimal attack, boolean isBoss){
        BigDecimal resAttack = new BigDecimal(attack.toString());
        if(!isBoss){
            int attackAdd = battleResultData.getAttackAdd();
            int reduceAttack = battleResultData.getBossReduceAttack();
            resAttack = resAttack.multiply(BigDecimal.valueOf(attackAdd + 1000)).divide(BigDecimal.valueOf(1000), 10, BigDecimal.ROUND_UP);
            //大于百分百就是扣百分百
            if(reduceAttack > 1000){
                reduceAttack = 1000;
            }
            resAttack = resAttack.multiply(BigDecimal.valueOf(1000 - reduceAttack)).divide(BigDecimal.valueOf(1000), 10, BigDecimal.ROUND_UP);
        }else if(isBoss){
            int attackAdd = battleResultData.getBossAttackAdd();
            int reduceAttack = battleResultData.getReduceAttack();
            resAttack = resAttack.multiply(BigDecimal.valueOf(attackAdd + 1000)).divide(BigDecimal.valueOf(1000), 10, BigDecimal.ROUND_UP);
            //大于百分百就是扣百分百
            if(reduceAttack > 1000){
                reduceAttack = 1000;
            }
            resAttack = resAttack.multiply(BigDecimal.valueOf(1000 - reduceAttack)).divide(BigDecimal.valueOf(1000), 10, BigDecimal.ROUND_UP);
        }
        return resAttack;
    }

    //为了显示吧公式改了变成每一步算一次向上取整
    private BigDecimal getBuffAndReduceAttackVersion2(TwinsBattleResultData battleResultData, BigDecimal attack, boolean isBoss){
        BigDecimal resAttack = new BigDecimal(attack.toString());
        if(!isBoss){
            resAttack = resAttack.add(BigDecimal.valueOf(battleResultData.getAddAttackValue()));
            resAttack = resAttack.subtract(BigDecimal.valueOf(battleResultData.getReduceAttackValue()));
        }else if(isBoss){
            resAttack = resAttack.add(BigDecimal.valueOf(battleResultData.getBossAddAttackValue()));
            resAttack = resAttack.subtract(BigDecimal.valueOf(battleResultData.getBossReduceAttackValue()));
        }
        return resAttack;
    }

    //只算加成的攻击力，回血用
    private BigInteger getBuffAttack(TwinsBattleResultData battleResultData, BigInteger attack, boolean isBoss){
        BigInteger resAttack = new BigInteger(attack.toString());
        if(!isBoss){
            int attackAdd = battleResultData.getAttackAdd();
            resAttack = resAttack.multiply(BigInteger.valueOf(attackAdd + 1000)).divide(BigInteger.valueOf(1000));
        }else if(isBoss){
            int attackAdd = battleResultData.getBossAttackAdd();
            resAttack = resAttack.multiply(BigInteger.valueOf(attackAdd + 1000)).divide(BigInteger.valueOf(1000));
        }
        return resAttack;
    }

    //计算我的攻击力和血量
    private void calUserData(){
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        if(twinsConfig == null || twinsConfig.getActivityInfo() == null || !ActivityMgr.activityInShowTime(twinsConfig.getActivityInfo())){
            return;
        }
        if(null == userData){
            return;
        }
        Map<Integer, UserPatrons> userPatronsMap = player.getModule(PatronsModule.class).getUserPatronsMap();
        BigDecimal patronsNum = BigDecimal.valueOf(userPatronsMap.size());
        BigDecimal patronsLevel = BigDecimal.ZERO;
        if(userPatronsMap.size() == 0){
            patronsLevel = BigDecimal.ONE;
            patronsNum = BigDecimal.ONE;
        }
        for(UserPatrons userPatrons : userPatronsMap.values()){
            patronsLevel = patronsLevel.add(BigDecimal.valueOf(userPatrons.getLevel()));
        }

        BigDecimal maxBool = patronsNum.multiply(BigDecimal.valueOf(twinsConfig.getMaxBoolMulValue()));
        BigDecimal maxAttack = patronsLevel.multiply(BigDecimal.valueOf(twinsConfig.getMaxAttackMulValue()));
//        BigInteger maxBool = BigInteger.ONE;
//        BigInteger maxAttack = BigInteger.ONE;
        for(TwinsUserKungFuData kungFuData : userData.getOwnKungFuMap().values()){
            if(kungFuData.getLevel() == 0){
                continue;
            }
            TwinsKungFuConfig twinsKungFuConfig = twinsConfig.getKungFuConfig(kungFuData.getKungFuId(),kungFuData.getLevel());
            int param1 = twinsKungFuConfig.getSkillEffectList().get(0);
            int param2 = twinsKungFuConfig.getSkillEffectList().get(1);
            maxAttack = maxAttack.add(BigDecimal.valueOf(param1));
            maxBool = maxBool.add(BigDecimal.valueOf(param2));
        }
        int attCombValue = TwinsMgr.getCombAdd(userData.getUnlockCombList(), eTwinsKungFuCombType.DiyishenjianComb.getValue());
        int boolCombValue = TwinsMgr.getCombAdd(userData.getUnlockCombList(), eTwinsKungFuCombType.YihuajuexueComb.getValue());
        maxAttack = maxAttack.multiply(BigDecimal.valueOf(attCombValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);
        maxBool = maxBool.multiply(BigDecimal.valueOf(boolCombValue + 1000)).divide(BigDecimal.valueOf(1000),0,BigDecimal.ROUND_UP);

        userData.setMaxBool(maxBool.toString());
        userData.setMaxAttack(maxAttack.toString());
    }

    //上了第二张卡了开始战斗，是不是决出胜负了
    private List<TwinsBattleData> processBattle(){
        List<TwinsBattleData> retList = new ArrayList<>();
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        List<TwinsBattleData> battleDataList = new ArrayList<>();
        List<TwinsKungFuData> battleKungFuList = new ArrayList<>();
        //卡数量不对
        if(userData.getEmKungFuList().size() > 2){
            log.info("绝代{}关卡{},boss{}的卡多了",TwinsMgr.getActivityId(),userData.getMissionId(),userData.getBossId());
            List<TwinsKungFuData> tempList = new ArrayList<>();
            tempList.add(userData.getEmKungFuList().get(userData.getEmKungFuList().size() - 1));
            tempList.add(userData.getEmKungFuList().get(userData.getEmKungFuList().size() - 2));
            userData.setEmKungFuList(tempList);
        }
        if(userData.getEmKungFuList().size() < 2){
            log.info("绝代{}关卡{},boss{}的卡少了",TwinsMgr.getActivityId(),userData.getMissionId(),userData.getBossId());
            List<TwinsKungFuData> tempList = new ArrayList<>();
            tempList.add(userData.getEmKungFuList().get(userData.getEmKungFuList().size() - 1));
            tempList.add(userData.getEmKungFuList().get(userData.getEmKungFuList().size() - 1));
            userData.setEmKungFuList(tempList);
        }

        battleKungFuList.addAll(userData.getUpKungFuList());
        battleKungFuList.addAll(userData.getEmKungFuList());
        int myAnger = 0;
        int emAnger = 0;
        TwinsBattleResultData battleResultData = new TwinsBattleResultData();
        for(int i = 0; i < battleKungFuList.size();i++){
            TwinsKungFuData battleKungFu = battleKungFuList.get(i);
            TwinsBattleData battleData = null;
            if(i < 2){
                battleData = makeBattleData(battleResultData,true,battleKungFu);
                myAnger = myAnger + battleKungFu.getAnger();
            }else{
                battleData = makeBattleData(battleResultData,false,battleKungFu);
                emAnger = emAnger + battleKungFu.getAnger();
            }
            battleData.setKfId(battleKungFu.getId());
            battleData.setKungFuId(battleKungFu.getKungFuId());
            battleData.setLevel(battleKungFu.getLevel());
            battleData.setAnger(battleKungFu.getAnger());
            battleDataList.add(battleData);
        }
        //把投点的变化值重新算一遍
        for(int i = 0; i < battleDataList.size();i++){
            TwinsBattleData battleData = battleDataList.get(i);
            if(i < 2){
                if(battleData.getReduceFaceAnger() != 0){
                    emAnger = emAnger - battleData.getReduceFaceAnger();
                    battleData.setValue2(emAnger + "");
                }
            }else{
                if(battleData.getReduceFaceAnger() != 0){
                    myAnger = myAnger - battleData.getReduceFaceAnger();
                    battleData.setValue2(myAnger + "");
                }
            }
        }
        if(myAnger > emAnger){
            TwinsBattleData battleData = makeBattleData(battleResultData,true,null);
            battleDataList.add(battleData);
        }else if(emAnger > myAnger){
            TwinsBattleData battleData = makeBattleData(battleResultData,false,null);
            battleDataList.add(battleData);
        }


        BigInteger missionBool = new BigInteger(userData.getMissionBool());
        BigInteger bossBool = new BigInteger(userData.getBossBool());
        for(TwinsBattleData processData : battleDataList){
            boolean isBeak = false;
            BigInteger value = new BigInteger(processData.getAttackValue());
            BigInteger recoveryValue = new BigInteger(processData.getRecoveryValue());
            if(processData.isMyCard()){
                if(recoveryValue.compareTo(BigInteger.ZERO) > 0){
                    missionBool = missionBool.add(recoveryValue);
                    BigInteger maxMissBool = new BigInteger(userData.getMissionMaxBool());
                    if(missionBool.compareTo(maxMissBool) > 0){
                        missionBool = maxMissBool;
                    }
                }
                //boss血量被打了大于0或者boss的血量已经是小于0了，boss是不会死的
                if(bossBool.compareTo(value) > 0 || bossBool.compareTo(BigInteger.ZERO) < 0){
                    if(value.compareTo(BigInteger.ZERO) > 0 && bossBool.compareTo(BigInteger.valueOf(-1)) == 0){
                        //最原始的无限生命boss的血是-1，变成0再开始扣血
                        bossBool = bossBool.add(BigInteger.ONE);
                    }
                    bossBool = bossBool.subtract(value);
                }else{
                    bossBool = BigInteger.ZERO;
                    isBeak = true;
                }
            }else{
                if(recoveryValue.compareTo(BigInteger.ZERO) > 0){
                    if(bossBool.compareTo(BigInteger.ZERO) > 0){
                        bossBool = bossBool.add(recoveryValue);
                        //回血不能回超过最大值
                        BigInteger maxBossBool = BigInteger.ZERO;
                        TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(userData.getMissionId());
                        if(missionConfig != null){
                            List<Integer> bossInfoList = missionConfig.getBossInfo(userData.getBossId());
                            maxBossBool = new BigInteger(String.valueOf(bossInfoList.get(0)));
                        }
                        if(bossBool.compareTo(maxBossBool) > 0){
                            bossBool = maxBossBool;
                        }
                    }
                }
                if(missionBool.compareTo(value) > 0){
                    missionBool = missionBool.subtract(value);
                }else{
                    missionBool = BigInteger.ZERO;
                    isBeak = true;
                }
            }

            TwinsKungFuConfig kungFuConfig = twinsConfig.getKungFuConfig(processData.getKungFuId(),processData.getLevel());
            if(kungFuConfig != null ){
                if(kungFuConfig.getKungfuType() == eTwinsKungFuType.Sabre.getValue()){
                    if(processData.isMyCard()){
                        processData.setValue2(bossBool.toString());
                    }else{
                        processData.setValue2(missionBool.toString());
                    }
                }
                if(kungFuConfig.getKungfuType() == eTwinsKungFuType.IntSkill.getValue()){
                    if(processData.isMyCard()){
                        processData.setValue2(missionBool.toString());
                    }else{
                        processData.setValue2(bossBool.toString());
                    }
                }
            }
            retList.add(processData);
            if(isBeak){
                break;
            }
        }
        userData.setMissionBool(missionBool.toString());
        userData.setBossBool(bossBool.toString());
        return retList;
    }

    //生成两张新的卡和怪物的卡，开始下一次战斗上卡
    private void nextProcess(){
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        userData.setUpKungFuList(new ArrayList<>());
        List<TwinsKungFuData> myKungFuList = userData.getMyKungFuList();
        myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
        myKungFuList.add(TwinsMgr.getSelfKungFu(userData,selfIndex.getAndIncrement()));
        userData.setMyKungFuList(myKungFuList);

        userData.setEmKungFuList(new ArrayList<>());
        List<TwinsKungFuData> emKungFuList = userData.getEmKungFuList();
        TwinsNpcConfig npcConfig = twinsConfig.getNpcConfig(userData.getBossId());
        if(npcConfig != null && npcConfig.getAnger() != 0 && userData.getBossRage() >= npcConfig.getAnger()){
            emKungFuList.addAll(TwinsMgr.getBossAngerKungFuList(userData.getBossId(),enemyIndex,userData.getMissionId()));
            userData.setBossRage(userData.getBossRage() - npcConfig.getAnger());
            if(emKungFuList.size() == 0){
                log.error("绝代{},怒气卡获取有问题,bossId{}",TwinsMgr.getActivityId(),userData.getBossId());
                emKungFuList.add(TwinsMgr.getBossKungFu(userData.getBossId(),enemyIndex.getAndIncrement(),userData.getMissionId()));
                emKungFuList.add(TwinsMgr.getBossKungFu(userData.getBossId(),enemyIndex.getAndIncrement(),userData.getMissionId()));
            }
        }else{
            emKungFuList.add(TwinsMgr.getBossKungFu(userData.getBossId(),enemyIndex.getAndIncrement(),userData.getMissionId()));
            emKungFuList.add(TwinsMgr.getBossKungFu(userData.getBossId(),enemyIndex.getAndIncrement(),userData.getMissionId()));
        }
        userData.setEmKungFuList(emKungFuList);

        //最终boss死不了要一直计算伤害，用伤害排行
        TwinsMissionConfig missionConfig = twinsConfig.getMissionConfig(userData.getMissionId());
        List<Integer> bossInfoList = missionConfig.getBossInfo(userData.getBossId());
        //打不死的boss血量-1
        if(bossInfoList.get(0) == -1){
            TwinsMissionDamageArgs args =
                    new TwinsMissionDamageArgs(BigInteger.valueOf(userData.getMissionId()),
                            BigInteger.ZERO.subtract(new BigInteger(userData.getBossBool())).toString());
            player.notifyListener(eGamePlayerEventType.TwinsPassDamageRank.getValue(),args);
        }
    }

    //打输了，重新开始
    private void gameOver(){
        if(userData.getMissionId() == TwinsMgr.getConfig().getLastMissionId()){
            //最终boss死不了要一直计算伤害，用伤害排行
            TwinsMissionConfig missionConfig = TwinsMgr.getConfig().getMissionConfig(userData.getMissionId());
            List<Integer> bossInfoList = missionConfig.getBossInfo(userData.getBossId());
            //打不死的boss血量-1
            if(bossInfoList.get(0) == -1){
                TwinsMissionDamageArgs args =
                        new TwinsMissionDamageArgs(BigInteger.valueOf(userData.getMissionId()),
                                BigInteger.ZERO.subtract(new BigInteger(userData.getBossBool())).toString());
                player.notifyListener(eGamePlayerEventType.TwinsPassDamageRank.getValue(),args);
            }
        }
        userData.setMyKungFuList(new ArrayList<>());
        userData.setEmKungFuList(new ArrayList<>());
        userData.setUpKungFuList(new ArrayList<>());
        userData.setBossId(0);
        userData.setEnterMission(false);

    }

    //boss被打死了下一个boss
    private void nextBoss(){
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        int nextBossId = TwinsMgr.getNextBossId(userData.getMissionId(),userData.getBossId());
        TwinsMissionConfig twinsMissionConfig = twinsConfig.getMissionConfig(userData.getMissionId());
        List<Integer> bossInfoList = twinsMissionConfig.getBossInfo(nextBossId);

        userData.setBossId(nextBossId);
        userData.setBossBool(String.valueOf(bossInfoList.get(0)));
        userData.setBossRage(0);
        nextProcess();
    }

    //电脑挂了,没有下一个boss了
    private void nextMission(){
        if(player.getModule(AttributeModule.class).getAttribute(ePlayerAttrType.TwinsAutoPassMissionId) < userData.getMissionId()){
            player.getModule(AttributeModule.class).setAttribute(ePlayerAttrType.TwinsAutoPassMissionId,userData.getMissionId());
        }
        TwinsMissionDamageArgs args = new TwinsMissionDamageArgs(BigInteger.valueOf(userData.getMissionId()),"0");
        player.notifyListener(eGamePlayerEventType.TwinsPassDamageRank.getValue(),args);

        int nextMissionId = TwinsMgr.getNextMissionId(userData.getMissionId());
        if(nextMissionId == 0){
            int nowMissionId = userData.getMissionId();
            log.error("绝代{}找不到下一关的配置了，这一关{}继续打吧",TwinsMgr.getActivityId(),nowMissionId);
            nextMissionId = nowMissionId;
        }
        userData.setMissionId(nextMissionId);
        userData.setMyKungFuList(new ArrayList<>());
        userData.setEmKungFuList(new ArrayList<>());
        userData.setUpKungFuList(new ArrayList<>());
        userData.setEnterMission(false);
    }


    //抽卡
    public void pveDrawKungFu(int num) {
        //更新完了有一直优化，要前几次抽奖必中什么卡，只能热更
        List<Integer> timesDrawKungFuList = TwinsMgr.getConfig().getDrawKungFuMustList();
        boolean checkMust = true;
        if(timesDrawKungFuList.size() == 0){
            checkMust = false;
        }
        Map<Integer,Integer> oMap = new ConcurrentHashMap<>(TwinsMgr.getConfig().getOwnKungFuMap());
        for(TwinsUserKungFuData kfData : userData.getOwnKungFuMap().values()){
            //如果有卡不是初始卡也不是必中卡，那就说明玩家已经跳出了必中的魔咒了，没必要判断他抽了几次了，不需要必中卡了
            if(!timesDrawKungFuList.contains(kfData.getKungFuId()) && !oMap.containsKey(kfData.getKungFuId())){
                checkMust = false;
                break;
            }
        }
        Map<Integer, Map<Integer, TwinsKungFuConfig>> kungfuConfigMap = TwinsMgr.getConfig().getKungFuConfigMap();
        List<Integer> drawExpList = TwinsMgr.getConfig().getDrawExpList();
        //判断玩家抽了几次了
        int drawTimes = 99;
        //功夫id，经验
        Map<Integer,Integer> userKfMap = new ConcurrentHashMap<>();
        //第几次抽奖，功夫id，经验
        Map<Integer,Map<Integer,Integer>> isMap = new ConcurrentHashMap<>();
        if(checkMust){
            Map<Integer,Integer> oExpMap = new ConcurrentHashMap<>();
            for(int kungFuId : oMap.keySet()){
                int level = oMap.get(kungFuId);
                for(TwinsKungFuConfig tempData : kungfuConfigMap.get(kungFuId).values()){
                    if(tempData.getLevel() <= level){
                        oExpMap.put(kungFuId,oExpMap.getOrDefault(kungFuId,0) + tempData.getCost());
                    }
                }
            }
            isMap.put(0,oExpMap);
            for(int i = 0; i < timesDrawKungFuList.size(); i++){
                if(i==0){
                    isMap.put(i+1,new ConcurrentHashMap<>(oExpMap));
                }else{
                    isMap.put(i+1,new ConcurrentHashMap<>(isMap.get(i)));
                }
                int dKungfuId = timesDrawKungFuList.get(i);
                TwinsKungFuConfig dKungFuConifg = kungfuConfigMap.get(dKungfuId).get(1);
                int addExp = drawExpList.get(dKungFuConifg.getQuality() - 1);
                isMap.get(i+1).put(dKungfuId,oExpMap.getOrDefault(dKungfuId,0) + addExp);
            }
            for(TwinsUserKungFuData kfData : userData.getOwnKungFuMap().values()){
                userKfMap.put(kfData.getKungFuId(),userKfMap.getOrDefault(kfData.getKungFuId(),0) + kfData.getExp());
                int level = kfData.getLevel();
                for(TwinsKungFuConfig tempData : kungfuConfigMap.get(kfData.getKungFuId()).values()){
                    if(tempData.getLevel() <= level){
                        userKfMap.put(kfData.getKungFuId(),userKfMap.getOrDefault(kfData.getKungFuId(),0) + tempData.getCost());
                    }
                }
            }
            for(int i = 0; i < timesDrawKungFuList.size(); i++){
                if(isMap.get(i).size() == userKfMap.size()){
                    boolean isThis = true;
                    for(int kfId : isMap.get(i).keySet()){
                        int userExp = userKfMap.get(kfId);
                        int configExp = isMap.get(i).get(kfId);
                        if(userExp != configExp){
                            isThis = false;
                            break;
                        }
                    }
                    if(isThis){
                        drawTimes = i;
                        break;
                    }
                }
            }
        }

        TwinsProto.TwinsKungFuDrawRespMsg.Builder respMsg = TwinsProto.TwinsKungFuDrawRespMsg.newBuilder();
        respMsg.setRet(0);
        Map<Integer, TwinsUserKungFuData> userKungFuDataMap = userData.getOwnKungFuMap();
        List<String> costList = TwinsMgr.getConfig().getDrawCostList();
        String cost = "";
        if(num == 1){
            cost = costList.get(0);
        }else if(num == 10){
            cost = costList.get(1);
        }else if(num == 100){
            //一百连十次十连
            Property costPro = new Property();
            for(int i = 0;i < 10;i++){
                costPro.addProperty(PropertyHelper.parseStringToProperty(costList.get(1)));
            }
            cost = PropertyHelper.parsePropertyToString(costPro);
        }
        if(!player.getModule(CurrencyModule.class).currencyIsEnough(PropertyHelper.parseStringToProperty(cost))){
            respMsg.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
            player.sendPacket(Protocol.U_TWINS_KUNG_FU_DRAW, respMsg);
            return;
        }
        player.getModule(CurrencyModule.class).removeCurrency(PropertyHelper.parseStringToProperty(cost), eLogMoneyType.Twins,eLogMoneyType.TwinsDrawCost);

        for(int i = 0; i < num;i++){
            TwinsDrawData drawData = null;
            if(drawTimes + 1 <= timesDrawKungFuList.size()){
                int dkfId = timesDrawKungFuList.get(drawTimes);
                drawData = new TwinsDrawData();
                drawData.setKungFuId(dkfId);
                TwinsKungFuConfig dKungFuConifg = kungfuConfigMap.get(dkfId).get(1);
                int addExp = drawExpList.get(dKungFuConifg.getQuality() - 1);
                drawData.setValue(addExp);
                List<Integer> drawAddIntegralList = TwinsMgr.getConfig().getDrawAddIntegralList();
                int addIntegral = drawAddIntegralList.get(dKungFuConifg.getQuality() - 1);
                drawData.setAddIntegralValue(addIntegral);
            }else{
                drawData = TwinsMgr.randomKungFu(userData.getOwnKungFuMap());
            }
            if(drawData.getAddIntegralValue() > 0){
                String integralReward = TwinsMgr.getConfig().getTwinsShopItemId() + "=" + drawData.getAddIntegralValue();
                player.getModule(CurrencyModule.class).addCurrency(integralReward,eLogMoneyType.Twins,eLogMoneyType.TwinsDrawKungFuIntegral);
            }
            TwinsProto.TwinsKungFuDrawTempMsg.Builder drawMsg = TwinsProto.TwinsKungFuDrawTempMsg.newBuilder();
            drawMsg.setKungfuId(drawData.getKungFuId());
            drawMsg.setValue(drawData.getValue());
            drawMsg.setIntegral(drawData.getAddIntegralValue());
            if(userKungFuDataMap.containsKey(drawData.getKungFuId())){
                TwinsUserKungFuData userKungFuData = userKungFuDataMap.get(drawData.getKungFuId());
                userKungFuData.setExp(userKungFuData.getExp() + drawData.getValue());
                drawMsg.setIsNew(false);
            }else{
                TwinsUserKungFuData userKungFuData = new TwinsUserKungFuData();
                userKungFuData.setKungFuId(drawData.getKungFuId());
                userKungFuData.setLevel(0);
                userKungFuData.setExp(userKungFuData.getExp() + drawData.getValue());
                userKungFuDataMap.put(userKungFuData.getKungFuId(),userKungFuData);
                drawMsg.setIsNew(true);
            }
            respMsg.addKungFu(drawMsg);
            LogTwinsDrawKungFu log = new LogTwinsDrawKungFu(
                    userData.getActivityId(),userData.getUserId(),cost,drawData.getKungFuId(),
                    drawData.getValue(),drawData.getAddIntegralValue()
            );
            LogMgr.addLogTwinsKungFuDraw(log);
            drawTimes++;
        }
        Map<Integer,TwinsProto.TwinsKungFuDrawTempMsg.Builder> mergeMap = new ConcurrentHashMap<>();
        for(TwinsProto.TwinsKungFuDrawTempMsg oneMsg : respMsg.getKungFuList()){
            if(!mergeMap.containsKey(oneMsg.getKungfuId())){
                TwinsProto.TwinsKungFuDrawTempMsg.Builder drawMsg = TwinsProto.TwinsKungFuDrawTempMsg.newBuilder();
                drawMsg.setKungfuId(oneMsg.getKungfuId());
                drawMsg.setValue(oneMsg.getValue());
                drawMsg.setIntegral(oneMsg.getIntegral());
                drawMsg.setIsNew(oneMsg.getIsNew());
                mergeMap.put(oneMsg.getKungfuId(),drawMsg);
            }else{
                TwinsProto.TwinsKungFuDrawTempMsg.Builder drawMsg = mergeMap.get(oneMsg.getKungfuId());
                drawMsg.setIntegral(drawMsg.getIntegral() + oneMsg.getIntegral());
                drawMsg.setValue(drawMsg.getValue() + oneMsg.getValue());
                if(!drawMsg.getIsNew()){
                    drawMsg.setIsNew(oneMsg.getIsNew());
                }
            }
        }
        respMsg.clearKungFu();
        for(TwinsProto.TwinsKungFuDrawTempMsg.Builder addMsg : mergeMap.values()){
            respMsg.addKungFu(addMsg);
        }
        userData.setOwnKungFuMap(userKungFuDataMap);
        player.sendPacket(Protocol.U_TWINS_KUNG_FU_DRAW, respMsg);
        //解锁一下组合
        unlockKungFuComb();
        calUserData();
        updateCrossUserData();
        syncUserData();
    }

    //升级技能
    public void pveUpgradeKungFu(int kungFuId) {
        TwinsProto.TwinsKungFuUpgradeRespMsg.Builder respMsg = TwinsProto.TwinsKungFuUpgradeRespMsg.newBuilder();
        respMsg.setRet(0);
        Map<Integer, TwinsUserKungFuData> userKungFuDataMap = userData.getOwnKungFuMap();
        if(!userKungFuDataMap.containsKey(kungFuId)){
            respMsg.setRet(GameErrorCode.E_TWINS_KUNGFU_UPGRADE_EXP);
            player.sendPacket(Protocol.U_TWINS_KUNG_FU_UPGRADE, respMsg);
            return;
        }
        TwinsUserKungFuData userKungFuData = userKungFuDataMap.get(kungFuId);
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        TwinsKungFuConfig kungFuConfig = twinsConfig.getKungFuConfig(kungFuId,userKungFuData.getLevel());
        TwinsKungFuConfig nextKungFuConfig = twinsConfig.getKungFuConfig(kungFuId,userKungFuData.getLevel() + 1);
        if(nextKungFuConfig == null || nextKungFuConfig.getCost() > userKungFuData.getExp()){
            respMsg.setRet(GameErrorCode.E_TWINS_KUNGFU_UPGRADE_EXP);
            player.sendPacket(Protocol.U_TWINS_KUNG_FU_UPGRADE, respMsg);
            return;
        }
        userKungFuData.setExp(userKungFuData.getExp() - nextKungFuConfig.getCost());
        userKungFuData.setLevel(userKungFuData.getLevel() + 1);
        List<TwinsKungFuCombConfig> unlockComList = unlockKungFuComb();
        for(TwinsKungFuCombConfig combConfig : unlockComList){
            TwinsProto.TwinsKungFuCombMsg.Builder combMsg = TwinsProto.TwinsKungFuCombMsg.newBuilder();
            combMsg.setType(combConfig.getType());
            combMsg.setLevel(combConfig.getLevel());
            respMsg.addComb(combMsg);
        }

        respMsg.setKungfuId(kungFuId);
        respMsg.setLevel(userKungFuData.getLevel());
        respMsg.setOBool(userData.getMaxBool());
        respMsg.setOAttack(userData.getMaxAttack());
        String oparam,nparam;
        oparam = userData.getMaxBool() + "|" + userData.getMaxAttack();
        calUserData();
        nparam = userData.getMaxBool() + "|" + userData.getMaxAttack();
        updateCrossUserData();
        syncUserData();

        respMsg.setNBool(userData.getMaxBool());
        respMsg.setNAttack(userData.getMaxAttack());
        player.sendPacket(Protocol.U_TWINS_KUNG_FU_UPGRADE, respMsg);

        LogTwinsKungFuUpgrade log = new LogTwinsKungFuUpgrade(
                userData.getActivityId(),userData.getUserId(),kungFuId,
                userKungFuData.getLevel()-1,userKungFuData.getLevel(),oparam,nparam
        );
        LogMgr.addLogTwinsKungFuUpgrade(log);
    }

    //武学遍历下看看解锁了什么
    public List<TwinsKungFuCombConfig> unlockKungFuComb(){
        Map<Integer, TwinsUserKungFuData> userKungFuDataMap = userData.getOwnKungFuMap();
        List<Integer> userCombList = userData.getUnlockCombList();
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        Map<Integer, Map<Integer, TwinsKungFuConfig>> kungfuConfigMap = twinsConfig.getKungFuConfigMap();
        Map<Integer, TwinsKungFuCombConfig> combConfigMap = twinsConfig.getKungFuCombConfigMap();
        Map<Integer,TwinsKungFuCombConfig> unlockCombMap = new ConcurrentHashMap<>();
        for(TwinsKungFuCombConfig combConfig : combConfigMap.values()){
            if(userCombList.contains(combConfig.getId()))continue;
            boolean isUnlock = true;
            if(!"0".equals(combConfig.getNeedOriginLevel())){
                List<Integer> needList = StringUtils.stringToIntegerList(combConfig.getNeedOriginLevel(),";");
                for(Integer kungFuId : kungfuConfigMap.keySet()){
                    TwinsKungFuConfig kungFuConfig = kungfuConfigMap.get(kungFuId).get(1);
                    if(kungFuConfig.getOriginType() == needList.get(0)){
                        if(!userKungFuDataMap.containsKey(kungFuId) || userKungFuDataMap.get(kungFuId).getLevel() < needList.get(1)){
                            isUnlock = false;
                            break;
                        }
                    }
                }
            }
            if(!"0".equals(combConfig.getNeedKungfuLevel())){
                List<Integer> needList = StringUtils.stringToIntegerList(combConfig.getNeedKungfuLevel(),";");
                for(Integer kungFuId : kungfuConfigMap.keySet()){
                    TwinsKungFuConfig kungFuConfig = kungfuConfigMap.get(kungFuId).get(1);
                    if(kungFuConfig.getKungfuType() == needList.get(0)){
                        if(!userKungFuDataMap.containsKey(kungFuId) || userKungFuDataMap.get(kungFuId).getLevel() < needList.get(1)){
                            isUnlock = false;
                            break;
                        }
                    }
                }
            }
            if(isUnlock){
                unlockCombMap.put(combConfig.getId(),combConfig);
            }
        }
        userCombList.addAll(unlockCombMap.keySet());
        userData.setUnlockCombList(userCombList);
        player.notifyListener(eGamePlayerEventType.TwinsKangfuComb.getValue(),new ConcurrentHashMap<>(userData.getOwnKungFuMap()));
        player.notifyListener(eGamePlayerEventType.TwinsKangfuAllLevel.getValue(),getAllKangFuLevel());
        for(int combId : unlockCombMap.keySet()){
            LogTwinsKungFuCombUnlock log = new LogTwinsKungFuCombUnlock(
                    userData.getActivityId(),userData.getUserId(),combId
            );
            LogMgr.addLogTwinsKungFuCombUplock(log);
        }
        return new ArrayList<>(unlockCombMap.values());

    }

    //组合武学解锁了哪些了
    public void pveKungFuComb() {
        TwinsProto.TwinsKungFuCombRespMsg.Builder respMsg = TwinsProto.TwinsKungFuCombRespMsg.newBuilder();
        respMsg.setRet(0);
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        if(twinsConfig == null){
            player.sendPacket(Protocol.U_TWINS_KUNG_FU_COMB, respMsg);
            return;
        }
        Map<Integer,Integer> typeLevelMap = new ConcurrentHashMap<>();
        for(int combId : userData.getUnlockCombList()){
            TwinsKungFuCombConfig combConfig = twinsConfig.getKungFuCombConfig(combId);
            if(combConfig != null){
                if(typeLevelMap.getOrDefault(combConfig.getType(),0) < combConfig.getLevel()){
                    typeLevelMap.put(combConfig.getType(),combConfig.getLevel());
                }
            }
        }
        for(int type : typeLevelMap.keySet()){
            TwinsProto.TwinsKungFuCombMsg.Builder combMsg = TwinsProto.TwinsKungFuCombMsg.newBuilder();
            combMsg.setType(type);
            combMsg.setLevel(typeLevelMap.get(type));
            respMsg.addComb(combMsg);
        }
        player.sendPacket(Protocol.U_TWINS_KUNG_FU_COMB, respMsg);
    }

    //扫荡
    public void pveGameMopUp(int missionId,int num) {
        hpRecovery();
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        TwinsProto.TwinsKungFuMopUpRespMsg.Builder respMsg = TwinsProto.TwinsKungFuMopUpRespMsg.newBuilder();
        respMsg.setRet(0);
        if(userData.getMissionId() <= missionId){
            respMsg.setRet(GameErrorCode.E_TWINS_PVE_MISSION_NO_PASS);
            player.sendPacket(Protocol.U_TWINS_MISSION_MOP_UP, respMsg);
            return;
        }
        TwinsMissionConfig missionConfig = twinsConfig.getMissionConfig(missionId);
        int hpReduce = missionConfig.getEnergyCost();
        if(userData.getHp() < num * hpReduce){
            respMsg.setRet(GameErrorCode.E_TWINS_MOP_UP_HP_NOT_ENOUGH);
            player.sendPacket(Protocol.U_TWINS_MISSION_MOP_UP, respMsg);
            return;
        }
        hpReduce(num * hpReduce);
        Property reward = new Property();
        for(int i = 0; i<num;i++){
            reward.addProperty(PropertyHelper.parseStringToProperty(missionConfig.getSweepRewards()));
            String randomReward = TwinsMgr.randomMopUpReward(missionId);
            reward.addProperty(PropertyHelper.parseStringToProperty(randomReward));
        }
        player.getModule(CurrencyModule.class).addCurrency(reward,eLogMoneyType.Twins,eLogMoneyType.TwinsMissionMopUpReward);
        respMsg.setReward(PropertyHelper.parsePropertyToString(reward));
        player.sendPacket(Protocol.U_TWINS_MISSION_MOP_UP, respMsg);
        syncUserData();
        LogTwinsPveBattle log = new LogTwinsPveBattle();
        log.setActivityId(userData.getActivityId());
        log.setUserId(userData.getUserId());
        log.setMissionId(missionId);
        log.setBossId(num);
        log.setRefreshTimes(0);
        log.setKungfuValue(userData.getHp() + num * hpReduce + "|" + userData.getHp());
        log.setBossKungfuValue("");
        log.setAttackValue("");
        log.setBossAttackValue("");
        log.setIsPass(2);
        log.setRandomReward(PropertyHelper.parsePropertyToString(reward));
        log.setPassReward("");
        log.setFailReward("");
        log.setTime(System.currentTimeMillis());
        LogMgr.addLogTwinsPveBattle(log);
    }

    //缓存一下门客数量和门客总等级，和上一次不一样才更新数据
    private int cachePatronsCount = 0;
    private int cachePatronsLevel = 0;
    public void patronsAbilityChange() {
        TwinsConfig twinsConfig = TwinsMgr.getConfig();
        if(twinsConfig == null || twinsConfig.getActivityInfo() == null || !ActivityMgr.activityInShowTime(twinsConfig.getActivityInfo())){
            return;
        }
        Map<Integer, UserPatrons> userPatronsMap = player.getModule(PatronsModule.class).getUserPatronsMap();
        BigDecimal patronsNum = BigDecimal.valueOf(userPatronsMap.size());
        BigDecimal patronsLevel = BigDecimal.ZERO;
        for(UserPatrons userPatrons : userPatronsMap.values()){
            patronsLevel = patronsLevel.add(BigDecimal.valueOf(userPatrons.getLevel()));
        }
        //缓存一下不要每次都更新
        if(cachePatronsCount != patronsNum.toBigInteger().intValue() || cachePatronsLevel != patronsLevel.toBigInteger().intValue()){
            cachePatronsCount = patronsNum.toBigInteger().intValue();
            cachePatronsLevel = patronsLevel.toBigInteger().intValue();
            calUserData();
            updateCrossUserData();
        }
    }
}
